package net.xdclass.util;


import com.jayway.jsonpath.JsonPath;
import io.restassured.response.Response;
import lombok.extern.slf4j.Slf4j;
import net.xdclass.dto.api.ApiJsonAssertionDTO;
import net.xdclass.enums.ApiAssertActionEnum;
import net.xdclass.enums.ApiAssertFieldFromEnum;
import net.xdclass.enums.ApiAssertTypeEnum;
import net.xdclass.enums.BizCodeEnum;
import net.xdclass.exception.BizException;
import net.xdclass.service.api.core.ApiRequest;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 小二
 */
@Slf4j
public class ApiAssertionUtil {

    /**
     * 断言行动分配器
     * @param value 值
     * @param expectValue 预期值
     * @return
     */
    public static boolean assertionDispatcher(String action, String value, String expectValue) {
        ApiAssertActionEnum assertActionEnum = ApiAssertActionEnum.valueOf(action);
        return switch (assertActionEnum) {
            // 包含
            case CONTAIN -> value.contains(expectValue);

            // 不包含
            case NOT_CONTAIN -> !value.contains(expectValue);

            // 相等
            case EQUAL -> value.equals(expectValue);

            // 不相等
            case NOT_EQUAL -> !value.equals(expectValue);

            // 大于
            case GREAT_THEN -> Long.parseLong(value) > Long.parseLong(expectValue);

            // 小于
            case LESS_THEN -> Long.parseLong(value) < Long.parseLong(expectValue);

            default -> throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_ASSERTION);
        };
    }

    /**
     * 断言来源分配器
     * @param request
     * @param response
     */
    public static void dispatcher(ApiRequest request, Response response) {
        if (request.getAssertion() == null) {
            return;
        }
        for (ApiJsonAssertionDTO assertion : request.getAssertionList()) {
            boolean state = true;
            String express = assertion.getExpress();
            String expectValue = assertion.getValue();
            ApiAssertFieldFromEnum fieldFromEnum = ApiAssertFieldFromEnum.valueOf(assertion.getFrom());
            try {
                if (ApiAssertTypeEnum.JSONPATH.name().equals(assertion.getType())) {
                    // jsonpath定位
                    state = switch (fieldFromEnum) {
                        case RESPONSE_CODE -> {
                            String stringify = String.valueOf(response.getStatusCode());
                            Object responseCode = JsonPath.read(stringify, express);
                            yield assertionDispatcher(assertion.getAction(), String.valueOf(responseCode), expectValue);
                        }

                        case RESPONSE_HEADER -> {
                            String stringify = JsonUtil.obj2Json(response.getHeaders());
                            Object responseHeader = JsonPath.read(stringify, express);
                            yield assertionDispatcher(assertion.getAction(), String.valueOf(responseHeader), expectValue);
                        }

                        case RESPONSE_DATA -> {

                            String stringify = response.getBody().asString();
                            //String stringify = JsonUtil.obj2Json(body);
                            Object responseBody = JsonPath.read(stringify, express);
                            yield assertionDispatcher(assertion.getAction(), String.valueOf(responseBody), expectValue);
                        }

                        default -> {
                            log.error("不支持的断言来源: {}", fieldFromEnum);
                            throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_FROM);
                        }
                    };

                } else if (ApiAssertTypeEnum.REGEXP.name().equals(assertion.getType())) {
                    // 正则表达式定位
                    Pattern pattern = Pattern.compile(express);
                    state = switch (fieldFromEnum) {
                        case RESPONSE_CODE -> {
                            String responseCode = String.valueOf(response.getStatusCode());
                            Matcher matcher = pattern.matcher(responseCode);
                            yield matcher.find() && assertionDispatcher(assertion.getAction(), matcher.group(), expectValue);
                        }

                        case RESPONSE_HEADER -> {
                            String responseHeader = JsonUtil.obj2Json(response.getHeaders());
                            Matcher matcher = pattern.matcher(responseHeader);
                            yield matcher.find() && assertionDispatcher(assertion.getAction(), matcher.group(), expectValue);
                        }

                        case RESPONSE_DATA -> {
                            String responseBody = JsonUtil.obj2Json(response.getBody().asString());
                            Matcher matcher = pattern.matcher(responseBody);
                            yield matcher.find() && assertionDispatcher(assertion.getAction(), matcher.group(), expectValue);
                        }

                        default ->{
                            log.error("不支持的断言来源: {}", fieldFromEnum);
                            throw new BizException(BizCodeEnum.API_OPERATION_UNSUPPORTED_FROM);
                        }

                    };
                }

                if (!state) {
                    // 断言失败
                    throw new BizException(BizCodeEnum.API_ASSERTION_FAILED);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new BizException(BizCodeEnum.API_ASSERTION_FAILED);
            }
        }
    }
}
